package com.baijiayun.liveuibase.toolbox.answerer;

import com.baijiayun.livecore.models.LPAnswerModel;
import com.baijiayun.livecore.models.LPAnswerSheetOptionModel;
import com.baijiayun.livecore.utils.LPRxUtils;
import com.baijiayun.liveuibase.base.BaseWindow;
import com.baijiayun.liveuibase.base.RouterListener;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

public class AnswererPresenter implements AnswererContract.Presenter {
    private AnswererContract.View view;
    private Disposable countDownDisposable;
    private Disposable closeDisposable;
    private CompositeDisposable disposables;
    private LPAnswerModel lpAnswerModel;
    private RouterListener routerListener;
    private long remainTime;
    private boolean hasShowAnswer = false;
    private boolean hasSubmit = false;
    private static final int CLOSE_DELAY = 5;

    public AnswererPresenter(AnswererContract.View view, RouterListener routerListener) {
        this.view = view;
        this.routerListener = routerListener;
        this.disposables = new CompositeDisposable();
    }

    @Override
    public void closeWindow() {
        routerListener.onDismissAnswerer();
    }

    @Override
    public void setAnswererDatas(LPAnswerModel lpAnswerModel) {
        this.lpAnswerModel = lpAnswerModel;
        remainTime = lpAnswerModel.duration;
        subscribe();
    }

    @Override
    public LPAnswerModel getAnswerDatas() {
        return lpAnswerModel;
    }

    @Override
    public boolean submitAnswers() {
        hasSubmit = routerListener.getLiveRoom().getToolBoxVM().submitAnswers(lpAnswerModel);
        return hasSubmit;
    }

    @Override
    public boolean reset() {
        int size = lpAnswerModel.options.size();
        for (int i = 0; i < size; i++) {
            LPAnswerSheetOptionModel lpAnswerSheetOptionModel = lpAnswerModel.options.get(i);
            lpAnswerSheetOptionModel.isActive = false;
        }
        view.onReset(lpAnswerModel);
        return true;
    }

    public void subscribe() {
        startTimer();
        disposables.add(routerListener.getLiveRoom().getToolBoxVM().getObservableOfAnswerEnd()
                .observeOn(AndroidSchedulers.mainThread()).subscribe(lpAnswerEndModel -> {
                    if (view == null) return;
                    if (lpAnswerEndModel.isRevoke) {
                        if (remainTime > 0) {
                            startCloseTimer();
                        }
                    } else {
                        if (lpAnswerModel.isShowAnswer) {
                            if (!hasShowAnswer) {
                                if (!hasSubmit) {
                                    reset();
                                }
                                view.onShowAnswer(lpAnswerModel);
                                hasShowAnswer = true;
                            }
                        } else {
                            if (remainTime > 0) {
                                startCloseTimer();
                            }
                        }
                    }
                }));
        disposables.add(routerListener.getLiveRoom().getToolBoxVM().getObservableOfAnswerStart()
                .observeOn(AndroidSchedulers.mainThread()).subscribe(lpAnswerModel -> {
                    if (view != null) view.onReset(lpAnswerModel);
                    this.lpAnswerModel = lpAnswerModel;
                    remainTime = lpAnswerModel.duration;
                    if(view != null)view.timeDown(remainTime);
                    startTimer();
                }));
    }

    private void startCloseTimer() {
        LPRxUtils.dispose(closeDisposable);
        LPRxUtils.dispose(countDownDisposable);
        if (view != null) {
            view.doOnClose();
            view.timeDown(0);
            view.timeDownClose(CLOSE_DELAY);
        }
        closeDisposable = Observable.interval(1, TimeUnit.SECONDS)
                .take(CLOSE_DELAY + 1).map(aLong -> aLong + 1).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
                    if (view == null) return;
                    view.timeDownClose(CLOSE_DELAY - aLong);
                    if (aLong == CLOSE_DELAY + 1) {
                        view.endAnswer();
                        LPRxUtils.dispose(closeDisposable);
                    }
                });
    }

    private void startTimer() {
        view.initView(lpAnswerModel);
        hasShowAnswer = false;
        LPRxUtils.dispose(closeDisposable);
        LPRxUtils.dispose(countDownDisposable);
        countDownDisposable = Observable.interval(1, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    if (view == null) return;
                    if (remainTime <= 0) {
                        if (lpAnswerModel.isShowAnswer) {
                            if (!hasShowAnswer) {
                                view.onShowAnswer(lpAnswerModel);
                                hasShowAnswer = true;
                            }
                        } else {
                            view.endAnswer();
                            LPRxUtils.dispose(countDownDisposable);
                            return;
                        }
                    }
                    remainTime--;
                    view.timeDown(remainTime);
                });
    }

    @Override
    public void destroy() {
        LPRxUtils.dispose(countDownDisposable);
        LPRxUtils.dispose(closeDisposable);
        LPRxUtils.dispose(disposables);
        routerListener = null;
        view = null;
    }
}
